from flask import Flask, request, jsonify, send_from_directory, Response
from flask_cors import CORS
from zhipuai import ZhipuAI
import os
import base64
import json
import random
import pdfkit
from datetime import datetime

# 获取当前文件所在目录的绝对路径
current_dir = os.path.dirname(os.path.abspath(__file__))

app = Flask(__name__, static_url_path='', static_folder=current_dir)
CORS(app)

# 初始化智谱AI客户端
API_KEY = "d0dfb31cb4ef4ca8b13aa6a485171538.xWyAtGVckhaqFynZ"
client = ZhipuAI(api_key=API_KEY)

# C语言题目类型列表
QUESTION_TYPES = [
    "基础语法", "数组", "指针", "函数", "结构体", "文件操作",
    "内存管理", "字符串处理", "算法实现", "链表操作"
]

# 难度级别
DIFFICULTY_LEVELS = ["初级", "中级", "高级"]

# 存储当前的题目和答案
current_question = None
current_answer = None
knowledge_base = {}  # 存储上传的文件内容

# 在现有代码基础上添加题目类型常量
QUESTION_TYPES = {
    "选择题": {
        "weight": 0.4,
        "format": """
- 题目：[题目描述]
A. [选项A]
B. [选项B]
C. [选项C]
D. [选项D]
答案：[正确选项]
解析：[详细解析]
"""
    },
    "填空题": {
        "weight": 0.3,
        "format": """
- 题目：[题目描述]
答案：[正确答案]
解析：[详细解析]
"""
    },
    "编程题": {
        "weight": 0.3,
        "format": """
- 题目描述：[详细描述]
输入格式：[输入说明]
输出格式：[输出说明]
示例：
输入：[示例输入]
输出：[示例输出]
参考代码：
```c
[代码实现]
```
解析：[详细解析]
"""
    }
}

@app.route('/')
def root():
    return send_from_directory(current_dir, 'index.html')

@app.route('/<path:path>')
def send_file(path):
    return send_from_directory(current_dir, path)

@app.route('/upload', methods=['POST'])
def upload_file():
    try:
        if 'file' not in request.files:
            return jsonify({'success': False, 'error': '没有上传文件'})
        
        file = request.files['file']
        if file.filename == '':
            return jsonify({'success': False, 'error': '没有选择文件'})
        
        # 获取文件扩展名
        file_ext = os.path.splitext(file.filename)[1].lower()
        
        # 如果是图片文件
        if file_ext in ['.jpg', '.jpeg', '.png', '.gif', '.bmp']:
            # 创建uploads目录（如果不存在）
            upload_dir = os.path.join(current_dir, 'uploads')
            os.makedirs(upload_dir, exist_ok=True)
            
            # 保存图片文件
            file_path = os.path.join(upload_dir, file.filename)
            file.save(file_path)
            
            # 返回图片URL
            return jsonify({
                'success': True,
                'message': '图片上传成功',
                'file_url': f'/uploads/{file.filename}'
            })
        
        # 如果是文本文件，尝试读取内容
        try:
            content = file.read().decode('utf-8')
        except UnicodeDecodeError:
            try:
                # 尝试其他编码
                file.seek(0)  # 重置文件指针
                content = file.read().decode('gbk')
            except UnicodeDecodeError:
                return jsonify({
                    'success': False,
                    'error': '不支持的文件格式或编码'
                })
        
        # 将文本内容转换为结构化知识库
        sections = content.split('###')
        structured_content = {
            'categories': []
        }
        
        current_category = None
        for section in sections:
            if not section.strip():
                continue
            
            lines = section.strip().split('\n')
            title = lines[0].strip()
            content = '\n'.join(lines[1:]).strip()
            
            # 检查是否是主要分类
            if title.isdigit() or '. ' in title:
                current_category = {
                    'name': title.split('. ')[-1].strip(),
                    'topics': [{
                        'title': '基本概念',
                        'content': content,
                        'examples': []
                    }]
                }
                structured_content['categories'].append(current_category)
            elif current_category:
                # 将代码示例和说明添加到当前分类
                if '```c' in content or '```' in content:
                    code_blocks = content.split('```')
                    for i in range(1, len(code_blocks), 2):
                        current_category['topics'][0]['examples'].append({
                            'code': code_blocks[i].strip(),
                            'description': '代码示例'
                        })
        
        # 保存到知识库
        knowledge_base[file.filename] = structured_content
        
        return jsonify({
            'success': True,
            'message': '文件上传成功',
            'content': content
        })
        
    except Exception as e:
        print(f"Upload error: {str(e)}")
        return jsonify({'success': False, 'error': str(e)})

# 添加静态文件路由
@app.route('/uploads/<path:filename>')
def uploaded_file(filename):
    return send_from_directory(os.path.join(current_dir, 'uploads'), filename)

@app.route('/chat', methods=['POST'])
def chat():
    try:
        data = request.json
        user_message = data.get('message', '')
        file_name = data.get('file')
        
        # 检查是否是批量生成请求
        is_batch = '批量' in user_message or '多道' in user_message
        
        if is_batch:
            # 解析需要生成的题目数量
            import re
            num_questions = 10  # 默认生成10道题
            num_match = re.search(r'(\d+)道', user_message)
            if num_match:
                num_questions = min(int(num_match.group(1)), 20)  # 限制最多20道题
            
            # 构建批量生成的系统提示词
            system_prompt = f"""你是一个专业的C语言题目生成助手。请生成{num_questions}道不同类型的C语言题目，包括选择题、填空题和编程题。

请按照以下分布生成题目：
1. 选择题：40%
2. 填空题：30%
3. 编程题：30%

每种类型的题目格式如下：

### 选择题
{QUESTION_TYPES['选择题']['format']}

### 填空题
{QUESTION_TYPES['填空题']['format']}

### 编程题
{QUESTION_TYPES['编程题']['format']}

请确保：
1. 题目难度适中，循序渐进
2. 知识点覆盖全面
3. 题目描述清晰准确
4. 答案和解析详细完整

---"""
        else:
            # 单道题目的提示词保持不变
            system_prompt = """你是一个专业的C语言题目生成助手。请生成一道完整的C语言编程题目。
            # ... 原有的单题提示词 ...
            """

        # 如果有知识库文件
        if file_name and file_name in knowledge_base:
            kb_content = knowledge_base[file_name]
            system_prompt += "\n\n参考以下知识：\n"
            for category in kb_content.get('categories', []):
                system_prompt += f"\n{category['name']}:\n"
                for topic in category['topics']:
                    system_prompt += f"{topic['content']}\n"
                    for example in topic.get('examples', []):
                        if example.get('code'):
                            system_prompt += f"\n示例代码：\n```c\n{example['code']}\n```\n"

        messages = [
            {
                "role": "system",
                "content": system_prompt
            },
            {
                "role": "user",
                "content": user_message
            }
        ]

        response = client.chat.completions.create(
            model="glm-4",
            messages=messages,
            stream=True,
            temperature=0.7,
            max_tokens=4000 if is_batch else 2000  # 批量生成增加token限制
        )

        def generate():
            current_section = ""
            for chunk in response:
                if chunk.choices[0].delta.content:
                    content = chunk.choices[0].delta.content
                    if "---" in content:
                        formatted_content = format_content(current_section)
                        yield f"data: {formatted_content}\n\n"
                        current_section = ""
                    else:
                        current_section += content
            
            if current_section:
                formatted_content = format_content(current_section)
                yield f"data: {formatted_content}\n\n"
            
            yield "data: [DONE]\n\n"

        return Response(generate(), mimetype='text/event-stream')

    except Exception as e:
        print(f"Chat error: {str(e)}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500

def format_content(content):
    """格式化内容为HTML"""
    # 清理多余的空格和换行
    content = ' '.join(content.split())
    
    # 替换Markdown标记为HTML
    content = content.replace("### ", '<h3 class="section-header">')
    content = content.replace("**", '<strong>')
    
    # 处理代码块
    if "```c" in content:
        content = content.replace("```c", '<div class="code-container"><pre class="code-block c-code"><code>')
        content = content.replace("```", '</code></pre><button class="copy-btn" title="复制代码"><i class="fas fa-copy"></i></button></div>')
    elif "```" in content:
        content = content.replace("```", '<pre class="code-block"><code>')
        content = content.replace("```", '</code></pre>')
    
    # 处理段落
    paragraphs = content.split('\n\n')
    formatted_paragraphs = []
    for p in paragraphs:
        if p.strip():
            formatted_paragraphs.append(f'<p>{p.strip()}</p>')
    
    return '\n'.join(formatted_paragraphs)

@app.route('/download-exam', methods=['POST'])
def download_exam():
    try:
        data = request.json
        content = data.get('content')
        
        # 生成PDF文件
        pdf_filename = f"C语言试卷_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
        pdf_path = os.path.join(current_dir, 'downloads', pdf_filename)
        
        # 创建downloads目录
        os.makedirs(os.path.dirname(pdf_path), exist_ok=True)
        
        # 添加CSS样式到HTML内容
        styled_content = f"""
        <html>
        <head>
            <meta charset="UTF-8">
            <style>
                body {{ font-family: Arial, sans-serif; line-height: 1.6; }}
                .section-header {{ color: #1565c0; border-bottom: 2px solid #e3f2fd; }}
                .code-block {{ background: #f8f9fa; padding: 15px; margin: 10px 0; }}
                .highlight {{ background: #e3f2fd; padding: 10px; margin: 10px 0; }}
            </style>
        </head>
        <body>
            {content}
        </body>
        </html>
        """
        
        # 配置PDF生成选项
        options = {
            'page-size': 'A4',
            'margin-top': '20mm',
            'margin-right': '20mm',
            'margin-bottom': '20mm',
            'margin-left': '20mm',
            'encoding': 'UTF-8',
            'no-outline': None,
            'enable-local-file-access': None
        }
        
        try:
            pdfkit.from_string(styled_content, pdf_path, options=options)
        except Exception as e:
            print(f"PDF generation error: {str(e)}")
            # 尝试使用备用方法生成PDF
            from reportlab.pdfgen import canvas
            from reportlab.lib.pagesizes import A4
            
            c = canvas.Canvas(pdf_path, pagesize=A4)
            c.drawString(72, 800, "C语言试卷")
            c.save()
        
        return jsonify({
            'success': True,
            'filename': pdf_filename
        })
        
    except Exception as e:
        print(f"Download error: {str(e)}")
        return jsonify({
            'success': False,
            'error': str(e)
        }), 500

if __name__ == '__main__':
    # 创建uploads目录
    os.makedirs(os.path.join(current_dir, 'uploads'), exist_ok=True)
    os.makedirs(os.path.join(current_dir, 'downloads'), exist_ok=True)
    print(f"Static folder path: {current_dir}")
    app.run(debug=True, port=5000) 